package com.pocket.cloud.gateway.filters;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.net.URI;

/**
 * 【cloud-gateway-4】
 * <p> 自定义全局过滤器，需实现 GlobalFilter。
 *     全局过滤器主要注册进spring容器即可生效。
 * @author zhaozhile
 */
@Component
public class VisitTimeGlobalFilter implements GlobalFilter, Ordered {

    private static final Logger LOGGER = LoggerFactory.getLogger(VisitTimeGlobalFilter.class);

    private static final String BEGIN_VISIT_TIME = "begin_visit_time";

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 前置过滤
        exchange.getAttributes().put(BEGIN_VISIT_TIME, System.currentTimeMillis());

        Mono<Void> result = chain.filter(exchange);

        // 前置过滤
        Long beginVisitTime = exchange.getAttribute(BEGIN_VISIT_TIME);
        if (beginVisitTime != null){
            URI uri = exchange.getRequest().getURI();
            LOGGER.info("request [{}:{}] uri [{}] query params [{}], cost：{} ms", uri.getHost(), uri.getPort(), uri.getPath(), (System.currentTimeMillis() - beginVisitTime), uri.getRawQuery());
        }

        return result;
    }

    // webflux 写法
//    @Override
//    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//
//        exchange.getAttributes().put(BEGIN_VISIT_TIME, System.currentTimeMillis());
//
//        return chain.filter(exchange).then(Mono.fromRunnable(()->{
//                Long beginVisitTime = exchange.getAttribute(BEGIN_VISIT_TIME);
//                if (beginVisitTime != null){
//                    URI uri = exchange.getRequest().getURI();
//                    LOGGER.info("request [{}:{}] uri [{}] query params [{}], cost：{} ms", uri.getHost(), uri.getPort(), uri.getPath(), (System.currentTimeMillis() - beginVisitTime), uri.getRawQuery());
//                }
//        }));
//    }

    // 数字越小优先级越高
    @Override
    public int getOrder() {
        return 0;
    }
}
